package test.some;

import demo.ioc.Main;
import demo.ioc.my.core.annotation.Autowired;
import demo.ioc.my.core.annotation.Component;
import demo.ioc.my.core.annotation.Configuration;
import demo.ioc.my.core.annotation.Controller;
import demo.ioc.my.core.annotation.Repository;
import demo.ioc.my.core.annotation.Service;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

/**
 * Created by 张少昆 on 2018/3/18.
 */
public class A {
    @Autowired
    private String name;

    @Test
    public void r1() throws URISyntaxException, IOException{
        Map<Class<?>, Object> map = new HashMap<>();

        System.out.println(File.separator);

        Path path = Paths.get(this.getClass().getResource(".").toURI());
        String prefix = path.toFile().getPath() + File.separator;
        System.out.println(prefix);

        String pkg_prefix = this.getClass().getPackage().getName();
        System.out.println("---");
        Stream<Path> stream = Files.walk(path);
        // stream.filter(e -> e.endsWith("class") ) //FIXME path.endsWith 判断的是path，不是字符串，靠
        //                      .forEach(System.out::println);

        stream
                .map(Path::toFile)
                .filter(file -> file.canRead() && file.isFile() && file.getName().endsWith(".class"))
                .map(e -> {
                    String tmp = pkg_prefix + "." + e
                                                            .getPath()
                                                            .substring(prefix.length())
                                                            .replace(File.separatorChar, '.')
                                                            .replace(".class", "");
                    Class<?> clz = null;
                    try{
                        clz = Class.forName(tmp);
                    } catch(ClassNotFoundException e1){
                        e1.printStackTrace();
                    }
                    return clz;
                })
                .filter(e -> e.isAnnotationPresent(Component.class) || e.isAnnotationPresent(Controller.class) || e.isAnnotationPresent(Service.class) || e.isAnnotationPresent(Repository.class) || e.isAnnotationPresent(Configuration.class))
                .filter(e -> !e.isInterface())
                .forEach(e -> {
                    Class<?> superclass = e.getSuperclass();
                    // Class<?>[] classes = e.getClasses();//member
                    Class<?>[] interfaces = e.getInterfaces();

                    Object obj = null;
                    try{
                        obj = e.newInstance();
                        map.put(e, obj);//光这样还不够，还要存储其实现的接口的！
                        for(Class<?> anInterface : interfaces){
                            map.put(anInterface, obj);
                        }

                    } catch(InstantiationException e1){
                        e1.printStackTrace();
                    } catch(IllegalAccessException e1){
                        e1.printStackTrace();
                    }
                });

        System.out.println(map);
    }

    @Test
    public void r2(){
        Class<Main> mainClass = Main.class;
        System.out.println(mainClass.getPackage());
        System.out.println(mainClass.getPackage().getName());
        System.out.println(mainClass.getName());
        System.out.println(mainClass.getTypeName());
        System.out.println(mainClass.getSimpleName());
    }

    @Test
    public void r3() throws IllegalAccessException{
        Field[] fields = this.getClass().getDeclaredFields();

        for(Field field : fields){
            System.out.println(field.getDeclaringClass());//嗯？当前类？
            System.out.println(field.getType());
            System.out.println(field.getClass());
            System.out.println(Arrays.toString(field.getAnnotations()));
            System.out.println(field.getAnnotation(Autowired.class));
            System.out.println(field.isAnnotationPresent(Autowired.class));
            field.set(this, "haha");
            System.out.println(this.name);
        }
    }

    @Test
    public void url() throws MalformedURLException{
        String s = "http://localhost:8080/a/simple";
        URL url = new URL(s);
        System.out.println(url.getPath());

    }
}
